﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Vara.Utility;
using Vara.Person;
using Vara.Location;
using Vara.Warranty;
using Vara.Insurance;

namespace Vara.Asset
{
    public class AssetController : IAssetActions
    {
        #region IAssetActions Implementatations
        IAssetEvent_Actions AssetEventActions = new AssetEvent_Controller();

        protected List<IAsset> _assets = null;

        protected IPersonActions PersonController = new PersonController();
        protected ILocationActions LocationController = new Location_Controller();

        /// <summary>
        /// This method inserts a new asset into the asset tracking database using the Insert_Asset procedure
        /// </summary>
        /// <param name="asset"></param>
        public virtual void InsertAsset(IAsset asset)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// This method updates an asset into the asset tracking database using the Update_Asset procedure
        /// </summary>
        /// <param name="asset"></param>
        public virtual void UpdateAsset(IAsset asset)
        {
            ////if there is an asset to update
            //if (asset.ID > 0)
            //{
            //    using (ISqlEngine Engine = VaraSqlEngineProvider.Get())
            //    {
            //        ISqlEngineVariable[] var = this.getAssetVariables(asset).ToArray();
            //        Engine.ExecuteProcedure("Update_Asset", var);
            //        AssetEventActions.Insert(new AssetEvent("Updated", ""), asset);

            //        Engine.ExecuteProcedure("Delete_Asset_Warranties",
            //            VaraSqlEngineProvider.GetParam("@AssetId", asset.ID.ToString()));
            //        foreach (IWarranty IW in asset.WarrantyPolicies)
            //        {
            //            Engine.ExecuteProcedure("Insert_AssetWarranty",
            //            VaraSqlEngineProvider.GetParam("@AssetId", asset.ID.ToString()),
            //            VaraSqlEngineProvider.GetParam("@WarrantyId", IW.ID.ToString()));
            //        }

            //        Engine.ExecuteProcedure("Delete_Asset_Insurances",
            //            VaraSqlEngineProvider.GetParam("@AssetId", asset.ID.ToString()));
            //        foreach (IInsurance II in asset.InsurancePolicies)
            //        {
            //            Engine.ExecuteProcedure("Insert_AssetInsurance",
            //            VaraSqlEngineProvider.GetParam("@AssetId", asset.ID.ToString()),
            //            VaraSqlEngineProvider.GetParam("@InsuranceId", II.ID.ToString()));
            //        }
            //    }
            //    Refresh_Assets_List();
            //}
        }
        /// <summary>
        /// This method sets deleted = 1 in the asset tracking database using the Delete_Asset procedure
        /// </summary>
        /// <param name="asset"></param>
        public virtual void DeleteAsset(IAsset asset)
        {
            //if an asset exists to delete 
            if (asset.ID > 0)
            {
                using (ISqlEngine Engine = VaraSqlEngineProvider.Get())
                {
                    ISqlEngineVariable[] var = { VaraSqlEngineProvider.GetParam("@ID",asset.ID.ToString()),
                                                //add the puchase Id, valueId, AssetTypeId, in here
                                               };
                    Engine.ExecuteProcedure("Delete_Asset", var);
                    AssetEventActions.Insert(new AssetEvent("Deleted", ""), asset);

                }
                this.Assets.Remove(this.ReturnAsset(asset.ID));
                Refresh_Assets_List();
            }
        }
        /// <summary>
        /// This method returns a single asset from the asset tracking database where the id is passed to it
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual IAsset ReturnAsset(int id)
        {
            return this.Assets.Find(new Predicate<IAsset>(delegate(IAsset asset)
            {
                return asset.ID == id;
            }));
        }
        /// <summary>
        /// This method returns all of the assets from the asset tracking database
        /// </summary>
        public virtual void Refresh_Assets_List()
        {
            //create a table called TableOfAssets and use the Return_Assets stored procedure to populate it
            DataTable TableOfAssets = this.GetAssetsTable();
            //if there are some assets in the table then bring back the details for each row and add it as an asset
            if (TableOfAssets.Rows.Count > 0)
            {
                _assets = new List<IAsset>();
                foreach (DataRow r in TableOfAssets.Rows)
                {
                    this.Assets.Add(this.setupAsset(r));
                }
            }
        }

        protected virtual Asset setupAsset(DataRow r)
        {
            Asset newAsset = new Asset((int)r["ID"]);
            //newAsset.Name = r["Name"].ToString();
            //newAsset.AssetNo = r["AssetNo"].ToString();
            //newAsset.LegacyAssetNo = r["LegacyAssetNo"].ToString();

            //int locId = (int)r["LocationId"];
            //if (locId != 0)
            //{
            //    bool internalLoc = (bool)r["LocationIsInternal"];

            //    newAsset.Location = this.LocationController.ReturnLocation(locId, internalLoc);
            //}
            //if (r["OwnerId"] != DBNull.Value)
            //{
            //    newAsset.Owner = this.PersonController.ReturnPerson(r["OwnerId"].ToString(), r["OwnerType"].ToString());
            //}


            //if (r["Value"] != DBNull.Value && r["ValueDate"] != DBNull.Value)
            //{
            //    newAsset.Value = new Asset.AssetValue();
            //    newAsset.Value.DateAndTime = (DateTime)r["ValueDate"];
            //    newAsset.Value.Value = double.Parse(r["Value"].ToString());
            //}

            //newAsset.Location = newAsset.Location == null ? new Vara.Location.Location() : newAsset.Location;
            //newAsset.Owner = newAsset.Owner == null ? new Vara.Person.Person() : newAsset.Owner;

            return newAsset;
        }

        protected virtual DataTable GetAssetsTable()
        {
            DataTable TableOfAssets = null;
            using (ISqlEngine Engine = VaraSqlEngineProvider.Get())
            {
                TableOfAssets = Engine.ExecuteProcedure("Return_Assets");
            }
            return TableOfAssets;
        }

        protected virtual List<ISqlEngineVariable> getAssetVariables(IAsset asset)
        {
            List<ISqlEngineVariable> returnValue = new List<ISqlEngineVariable>();
            //if (asset.ID != 0)
            //{
            //    returnValue.Add(VaraSqlEngineProvider.GetParam("@ID", asset.ID.ToString()));
            //}

            //returnValue.AddRange(new ISqlEngineVariable[] { 
            
            //    VaraSqlEngineProvider.GetParam("@Name",asset.Name.ToString()),
            //    VaraSqlEngineProvider.GetParam("@AssetNo",asset.AssetNo.ToString()),
            //    VaraSqlEngineProvider.GetParam("@LegacyAssetNo",asset.LegacyAssetNo.ToString())
            
            //});
            //if (asset.Location != null)
            //{
            //    if (asset.Location.ID != 0)
            //    {
            //        returnValue.Add(VaraSqlEngineProvider.GetParam("@locationId", asset.Location.ID));
            //        returnValue.Add(VaraSqlEngineProvider.GetParam("@locationInternal", asset.Location.IsInternal ? "1" : "0"));
            //    }
            //}
            //if (asset.Owner != null)
            //{
            //    returnValue.Add(VaraSqlEngineProvider.GetParam("@ownerId", asset.Owner.Reference));
            //    returnValue.Add(VaraSqlEngineProvider.GetParam("@ownerType", asset.Owner.TypeName));

            //}

            //if (asset.Value != null)
            //{
            //    returnValue.Add(VaraSqlEngineProvider.GetParam("@value", asset.Value.Value));
            //    returnValue.Add(VaraSqlEngineProvider.GetParam("@valueDate", asset.Value.DateAndTime, SqlDbType.DateTime));
            //}

            return returnValue;
        }

        public virtual List<IAsset> Assets
        {
            get
            {
                if (_assets == null)
                {
                    this.Refresh_Assets_List();
                }
                return _assets;
            }
        }

        #endregion

        // the code below is not implemented - copied from Person controller as a possible way of implementing the SQL engine
        //procedure variables in one place 

        ///// <summary>
        ///// Set up an IAsset instance from a datarow
        ///// </summary>
        ///// <param name="r"></param>
        ///// <returns></returns>
        //private IAsset SetupAsset(DataRow r)
        //{
        //    Asset newAsset = new Asset((int)r["ID"]);
        //    newAsset.Name = r["Name"].ToString();
        //    newAsset.AssetNo = r["AssetNo"].ToString();
        //    newAsset.LegacyAssetNo = r["LegacyAssetNo"].ToString();
        //    return newAsset;
        //}

        ///// <summary>
        ///// sets up the SQL parameters for the insert or update procedure
        ///// </summary>
        ///// <param name="asset"></param>
        ///// <returns></returns>
        //private List<VaraSqlEngine.VaraSqlEngineVariable> SetupAssetParameters(IAsset asset)
        //{
        //    List<VaraSqlEngine.VaraSqlEngineVariable> vars = new List<VaraSqlEngine.VaraSqlEngineVariable>();

        //    //add if if there is one 
        //    if (asset.ID > 0)
        //    {
        //        vars.Add(new VaraSqlEngine.VaraSqlEngineVariable("@ID", asset.ID.ToString()));
        //    }

        //    //create the main variables range
        //    vars.AddRange(new VaraSqlEngine.VaraSqlEngineVariable[]
        //    {
        //        new VaraSqlEngine.VaraSqlEngineVariable("@Name",asset.Name),
        //        new VaraSqlEngine.VaraSqlEngineVariable("@AssetNo",asset.AssetNo),
        //        new VaraSqlEngine.VaraSqlEngineVariable("@LegacyAssetNo",asset.LegacyAssetNo)
        //    });
        //    return vars;
        //}
    }
}
